package com.ning.ems;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * @author Ning 242741154@qq.com
 * @date 2020/6/5 11:10
 */
public class AddressOfObject {
    public static Unsafe unsafe;

    static {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String str = "666";
        String str1 = "666";
        String str2 = new String("666");
        System.out.println(addressOf(str));
        System.out.println(addressOf(str1));
        System.out.println(addressOf(str2));
        System.gc();
        System.out.println(addressOf(str1));
        System.out.println(addressOf(str2));
        System.out.println();
        class Student {
            Integer id;
            String name;
        }
        Student stu = new Student();
        stu.id = 12;
        stu.name = "666";
        Student stu1 = new Student();
        stu1.id = 12;
        stu1.name = "666";
        System.out.println(addressOf(stu));
        System.out.println(addressOf(stu1));
        System.out.println(addressOf(stu.id));
        System.out.println(addressOf(stu1.id));
        System.out.println(addressOf(stu.name));
        System.out.println();
        System.out.println(addressOf(1));
        System.out.println(addressOf(1));
        System.out.println(addressOf(2));
        System.out.println(addressOf(3));
        System.out.println(addressOf(4));
    }

    public static long addressOf(Object... objs) {
        long baseOffset = unsafe.arrayBaseOffset(Object[].class);
        int addressSize = unsafe.addressSize();
        long objectAddress;
        switch (addressSize) {
            case 4:
                objectAddress = unsafe.getInt(objs, baseOffset);
                break;
            case 8:
                objectAddress = unsafe.getLong(objs, baseOffset);
                break;
            default:
                throw new Error("unsupported address size: " + addressSize);
        }
        return objectAddress;
    }
}
